{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5_Python函数设计\n",
    "\n",
    "**函数定义**\n",
    "\n",
    "函数是组织好的，可重复使用的，用来实现单一，或相关联功能的代码段。 \n",
    "- 可以自己创建函数，这被叫做用户自定义函数。 \n",
    "- 函数代码块以 def 关键词开头，后接函数标识符名称和圆括号()。 \n",
    "- 任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。 \n",
    "- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。 \n",
    "- 函数内容以冒号起始，并且缩进。 \n",
    "- return [表达式] 结束函数，选择性地返回一个值给调用方。不带表达式的return相当于返回 None。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1、 函数语法\n",
    "def function_name( parameters ):\n",
    "\n",
    "    '函数_文档字符串'\n",
    "    functions\n",
    "    return [expression]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "36"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def fun_1(x):\n",
    "    '求平方'\n",
    "    a = x**2\n",
    "    return a\n",
    "\n",
    "fun_1(6)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2、 参数设置\n",
    "**必备参数**\n",
    "\n",
    "必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "18"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def fun_2(x,y):\n",
    "    return x+y\n",
    "\n",
    "fun_2(6,12)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**关键字参数**\n",
    "\n",
    "关键字参数和函数调用关系紧密，函数调用使用关键字参数来确定传入的参数值。 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "StockName: APPLE\n",
      "Price: 100\n"
     ]
    }
   ],
   "source": [
    "def fun_3(StockName,Price):\n",
    "    print('StockName:', StockName)\n",
    "    print('Price:',Price)\n",
    "    return\n",
    "\n",
    "fun_3(Price=100, StockName='APPLE')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**默认参数**\n",
    "\n",
    "调用函数时，缺省参数的值如果没有传入，则被认为是默认值。 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "StockName: APPLE\n",
      "Price: 100\n",
      "Market: NAS100\n"
     ]
    }
   ],
   "source": [
    "def fun_3(StockName,Price, Market='SPX500'):\n",
    "    print('StockName:', StockName)\n",
    "    print('Price:',Price)\n",
    "    print('Market:', Market)\n",
    "    return\n",
    "\n",
    "fun_3(Price=100, StockName='APPLE', Market='NAS100')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**不定长参数**\n",
    "\n",
    "你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数，和上述2种参数不同，声明时不会命名。 \n",
    "\n",
    "以一个＊开始的参数，代表一个任意长的元组，一个以＊＊开始的参数，代表一个字典：\n",
    "\n",
    "*agrs/ **kwargs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "agrs: ()\n",
      "kwargs: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}\n"
     ]
    }
   ],
   "source": [
    "def fun_4(*agrs, **kwargs):\n",
    "    print('agrs:',agrs)\n",
    "    print('kwargs:',kwargs)\n",
    "    return\n",
    "\n",
    "fun_4(a=1,b=2,c=3,d=4,e=5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 3、 return语句\n",
    "return语句[表达式]退出函数，选择性地向调用方返回一个表达式。\n",
    "\n",
    "不带参数值的return语句返回None。 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "def fun_5(a,b):\n",
    "    c = a+b\n",
    "#     print(c)\n",
    "    return\n",
    "\n",
    "print(fun_5(5,6))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 变量作用域\n",
    "(全局变量与局部变量)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "局部变量： 60\n",
      "全局变量： 66\n"
     ]
    }
   ],
   "source": [
    "answer = 66\n",
    "\n",
    "def fun_6(a,b):\n",
    "    answer = a+b\n",
    "    print('局部变量：', answer)\n",
    "    return answer\n",
    "\n",
    "fun_6(6,54)\n",
    "print('全局变量：',answer)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4、 匿名函数\n",
    "python 使用 lambda 来创建匿名函数。 \n",
    "- lambda只是一个表达式，函数体比def简单很多。 \n",
    "- lambda的主体是一个表达式，而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。 \n",
    "- lambda函数拥有自己的命名空间，且不能访问自有参数列表之外或全局命名空间里的参数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "60"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = 20\n",
    "fun_7 = lambda a ,b : a*b\n",
    "\n",
    "fun_7(6, 10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 5、 内嵌函数\n",
    "函数内部创建函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "55"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def fun_8(a, b):\n",
    "    c = a+b\n",
    "    def multiple(c,a):\n",
    "        return a*c\n",
    "    return multiple(c,a)\n",
    "\n",
    "fun_8(5,6)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
